﻿using log4net;
using Newtonsoft.Json;
using Spring.Core.IO;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Xml;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace OF.DistributeService.Server.Common
{
    public class Util
    {
        private static ILog logger = null;
        public static string postRequest(string url, byte[] btArr)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = Util.JSONContentType;
            request.ContentLength = btArr.Length;
            using (Stream myRequestStream = request.GetRequestStream())
            {
                myRequestStream.Write(btArr, 0, btArr.Length);
                myRequestStream.Close();
                string retString = null;
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream myResponseStream = response.GetResponseStream())
                    {
                        using (StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")))
                        {
                            retString = myStreamReader.ReadToEnd();
                        }
                    }
                    return retString;
                }
            }
        }

        public static string postRequest(string url, string postDataStr)
        {
            byte[] btArr = Encoding.UTF8.GetBytes(postDataStr);
            return postRequest(url, btArr);
        }

        
        static Util()
        {
            log4net.Config.XmlConfigurator.Configure();
            logger = LogManager.GetLogger(typeof(Util));
        }

        public const string UnExcepedException = "An unexcepected exception occur, please wait a moment and reload again!";

        public static List<List<T>> SplitGroup<T>(List<T> list, int groupSize)
        {
            List<List<T>> result = new List<List<T>>();
            List<T> currentList = new List<T>();
            foreach (var item in list)
            {
                currentList.Add(item);
                if (currentList.Count >= groupSize)
                {
                    result.Add(currentList);
                    currentList = new List<T>();
                }
            }
            if (currentList.Count > 0)
            {
                result.Add(currentList);
            }
            return result;
        }

        public static void LoopAction(Action action, int sleepIntervalSeconds)
        {
            try
            {
                while (true)
                {
                    try
                    {
                        action();
                    }
                    catch (Exception ex)
                    {
                        Util.DumpFile("DeleteLogAction Inner Exception:" + ex.ToString());
                    }
                    SleepNSeconds(sleepIntervalSeconds);
                }
            }
            catch (Exception ex)
            {
                SleepNSeconds(1);
                Util.DumpFile("DeleteLogAction Exit Exception:" + ex.ToString());
            }
        }

        public static void SleepNSeconds(int seconds)
        {
            for (int i1 = 0; i1 < seconds; i1++)
            {
                Thread.Sleep(1000);
            }
        }

        public static void EnsureExecute(Action action, int maxSleepSeconds)
        {
            while (true)
            {
                try
                {
                    action();
                    break;
                }
                catch (Exception ex)
                {
                    Util.DumpFile("Jpush thread save xml exception:" + ex.ToString());
                    SleepNSeconds(maxSleepSeconds);
                }
            }
        }

        public static byte[] GetMemoryStreamBytes(MemoryStream ms)
        {
            byte[] btArray = new byte[ms.Position];
            Array.Copy(ms.GetBuffer(), btArray, ms.Position);
            return btArray;
        }

        public static string GetBase64JsonString(object obj)
        {
            var str = GetJsonString(obj);
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(str));
        }

        public static string GetJsonString(object obj)
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new Newtonsoft.Json.JsonSerializerSettings
            {
                NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
                DateTimeZoneHandling = DateTimeZoneHandling.Local
            });
        }

        public static T GetJsonObject<T>(string str)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str, new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore });
        }

        public static object GetJsonObject(string str, Type type)
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject(str, type, new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore });
        }

        public static T GetSpring<T>() where T : class
        {
            string typeName = typeof(T).Name;
            IResource input = new FileSystemResource(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, typeName + ".config"));
            IObjectFactory factory = new XmlObjectFactory(input);
            return (T)factory.GetObject(typeName, typeof(T));
        }


        public static void DumpFile(string str)
        {
            logger.Error(str);
        }

        public static void DumpFile(object obj, Exception ex)
        {
            string str = string.Empty;
            if (obj != null)
            {
                str = obj.ToString();
            }
            str += ", Exception is:" + System.Environment.NewLine + ex.ToString();
            logger.Error(str);
        }

        public static ExecuteResult GetError(int code, string errorMessage)
        {
            return new ExecuteResult
            {
                IsSuccess = false,
                ErrorCode = code,
                ErrorMessage = errorMessage
            };
        }

        public static ExecuteResult<T> GetError<T>(int code, string errorMessage)
        {
            return new ExecuteResult<T>
            {
                IsSuccess = false,
                ErrorCode = code,
                ErrorMessage = errorMessage
            };
        }


        public static ExecuteResult GetSuccess()
        {
            return new ExecuteResult
            {
                IsSuccess = true
            };
        }

        public static ExecuteResult<T> GetSuccess<T>(T result)
        {
            return new ExecuteResult<T>
            {
                IsSuccess = true,
                Result = result
            };
        }

        public static bool IsEquals(byte[] btArr1, byte[] btArr2)
        {
            if (btArr1 == btArr2)
            {
                return true;
            }
            else
            {
                if (btArr1 == null || btArr2 == null)
                {
                    return false;
                }
            }

            if (btArr1.Length != btArr2.Length)
            {
                return false;
            }

            for (int i1 = 0; i1 < btArr1.Length; i1++)
            {
                if (btArr1[i1] != btArr2[i1])
                {
                    return false;
                }
            }
            return true;
        }
    }

    public class IgnoreCaseComparer : IEqualityComparer<string>
    {
        public bool Equals(string x, string y)
        {
            if (object.ReferenceEquals(x, y))
            {
                return true;
            }

            if (x == null || y == null)
            {
                return false;
            }
            return string.Equals(x, y, StringComparison.InvariantCultureIgnoreCase);
        }

        public int GetHashCode(string obj)
        {
            return obj == null ? 0 : obj.ToLower().GetHashCode();
        }
    }

    /// <summary>
    /// 返回结果
    /// </summary>
    public class ExecuteResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool IsSuccess { get; set; }
        /// <summary>
        /// 信息
        /// </summary>
        public string ErrorMessage { get; set; }
        /// <summary>
        /// 错误码
        /// </summary>
        public int ErrorCode { get; set; }

        public int RequestContext { get; set; }
    }

    public class ExecuteResult<T> : ExecuteResult
    {
        /// <summary>
        /// 返回数据
        /// </summary>
        public T Result { get; set; }
    }
}
